package rensoft.android.lang;

import static rensoft.java.lang.Lang.string;

import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import rensoft.android.ApplicationContext;
import rensoft.android.json.JSONImpl;
import rensoft.java.json.JSONContainer;
import rensoft.java.lang.Lang.Work;
import rensoft.java.lang.LangCore;
import rensoft.java.lang.LangCoreImplBase;
import rensoft.java.lang.Run;

public class AndroidLangCore extends LangCoreImplBase implements LangCore {

  private static final String LOG_TAG = "AndroidApplication";
  private final Handler handler;

  public AndroidLangCore() {
    handler = new Handler();
  }

  @Override
  public void alert(Object[] messages) {
    Toast.makeText(ApplicationContext.getContext(), getAlertString(messages), Toast.LENGTH_LONG)
        .show();
  }

  @Override
  public void debug(Object... values) {
    Log.d(LOG_TAG, getDebugString(values));
  }

  @Override
  public void doLater(int delay_miliseconds, Runnable runnable) {
    handler.postDelayed(runnable, delay_miliseconds);
  }

  @Override
  public void doLater(Runnable runnable) {
    handler.post(runnable);
  }

  @Override
  public void error(Throwable e, Object... values) {
    Log.e(LOG_TAG, createLogMessage(ERROR_TITLE, "", values), e);
  }

  @Override
  public void info(Object[] values) {
    StackTraceElement element = new Throwable().getStackTrace()[2];
    Log.i(LOG_TAG, createLogMessage(INFO_TITLE, createLogString(element), values));
  }

  @Override
  public JSONContainer json(String json_string) {
    return new JSONImpl().parse(json_string);
  }

  @Override
  public Work schedule(final int delay_miliseconds, final Run runnable) {
    return new Work() {
      private boolean stop = true;

      public void start() {
        stop = false;
        process();
      }

      public void stop() {
        stop = true;
      }

      private void process() {
        doLater(delay_miliseconds, new Run() {
          public void run() {
            if (!stop) {
              runnable.run();
              process();
            }
          }
        });
      }
    };
  }

  public void trace(Object... values) {
    Log.i(LOG_TAG, createLogMessage(INFO_TITLE, "", values), new Throwable());
  }

  @Override
  protected String createLogString(StackTraceElement element) {
    return string(" ", element.getClassName(), element.getMethodName(), element.getFileName(),
        element.getLineNumber());
  }

}
